package ln.gather.jsr.jcache.event;

import javax.cache.Cache;
import javax.cache.event.CacheEntryEvent;
import javax.cache.event.EventType;
import java.util.Objects;

/**
 * @Description GanericCacheEntryEvent
 * @Author zhangj
 * @Date 2022/11/17 22:28
 */
public class GanericCacheEntryEvent<K, V> extends CacheEntryEvent<K, V> {

    private final K key;

    private final V oldValue;

    private final V value;

    public GanericCacheEntryEvent(Cache source, EventType eventType, K key, V oldValue, V value) {
        super(source, eventType);
        Objects.requireNonNull(key, "The key must not be null!");
        Objects.requireNonNull(value, "The value must not be null!");
        this.key = key;
        this.oldValue = oldValue;
        this.value = value;
    }

    @Override
    public K getKey() {
        return key;
    }

    @Override
    public V getValue() {
        return value;
    }

    @Override
    public <T> T unwrap(Class<T> clazz) {
        return getSource().getCacheManager().unwrap(clazz);
    }

    @Override
    public V getOldValue() {
        return oldValue;
    }

    @Override
    public boolean isOldValueAvailable() {
        return oldValue != null;
    }

    public static <K, V> CacheEntryEvent<K, V> of(Cache source, EventType eventType, K key, V oldValue, V value) {
        return new GanericCacheEntryEvent<>(source, eventType, key, oldValue, value);
    }

    public static <K, V> CacheEntryEvent<K, V> createEvent(Cache source, K key,  V value) {
        return of(source, EventType.CREATED, key, null, value);
    }

    public static <K, V> CacheEntryEvent<K, V> updateEvent(Cache source, K key, V oldValue, V value) {
        return of(source, EventType.CREATED, key, oldValue, value);
    }

    public static <K, V> CacheEntryEvent<K, V> expiredEvent(Cache source,  K key, V oldValue) {
        return of(source, EventType.EXPIRED, key, oldValue, oldValue);
    }

    public static <K, V> CacheEntryEvent<K, V> removeEvent(Cache source,  K key, V oldValue) {
        return of(source, EventType.REMOVED, key, oldValue, oldValue);
    }

}
